﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Text.RegularExpressions;

namespace SourcePacker
{
    class Engine
    {
        public Engine()
        {
            Settings = new Settings();
        }

        public Settings Settings { get; set; }
        public SourceContainer SourceContainer { get; set; }

        public void analyseSources()
        {
            if (Settings.OutputHeaderFile.Length == 0)
            {
                Settings.IncludeExportHeaderIfNeeded = false;
                Settings.ExportHeaderFiles = new string[] { };
            }

            if (Settings.OutputSourceFile.Length == 0)
            {
                Settings.CondionalSourceFolders.Clear();
                Settings.SourceFolders = new string[] { };
            }

            List<string> additionalSourceFolders = new List<string>();

            foreach (var conditionalSourceFolder in Settings.CondionalSourceFolders)
                if (!isInAnyFolder(conditionalSourceFolder.Key, Settings.SourceFolders))
                    additionalSourceFolders.Add(conditionalSourceFolder.Key);

            if (additionalSourceFolders.Count > 0)
            {
                string[] sourceFolders = Settings.SourceFolders;

                Array.Resize(ref sourceFolders, sourceFolders.Length + additionalSourceFolders.Count);
                additionalSourceFolders.CopyTo(sourceFolders, Settings.SourceFolders.Length);
            }

            SourceContainer = new SourceContainer(Settings.ExportHeaderFiles,
                Settings.SourceFolders,
                Settings.CondionalSourceFolders,
                Settings.AdditionalIncludeFolders,
                Settings.SourceExtensions,
                Settings.ReplaceSystemInclude);
        }

        public void execute()
        {
            analyseSources();

            SourceContainer.pack(Settings.AppendFileSplitter, 
                Settings.IncludeExportHeaderIfNeeded,
                Settings.IncludeExportHeaderIfNeeded ? Path.GetFileName(Settings.OutputHeaderFile) : "");

            string packedText = SourceContainer.PackedExportHeader.ToString();

            if (Settings.OutputHeaderFile.Length > 0)
                File.WriteAllText(Settings.OutputHeaderFile, 
                    Settings.CompactSource ?
                    new Compactor(packedText).Result : packedText);

            packedText = SourceContainer.PackedSource.ToString();

            if (Settings.OutputSourceFile.Length > 0)
                File.WriteAllText(Settings.OutputSourceFile,
                    Settings.CompactSource ?
                    new Compactor(packedText).Result : packedText);
        }

        bool isInAnyFolder(string child, string[] parents)
        {
            foreach (var parent in parents)
                if (SourceContainer.isInFolder(child, parent))
                    return true;

            return false;
        }
    }
}
